﻿using System.Collections;
using System.Collections.Generic;

namespace Socium.Domain.Collections {
	public sealed class CollectionResult<T> : IEnumerable<T> {
		readonly ICollection<T> _collection;

		public CollectionResult(ICollection<T> collection) {
			_collection = collection;
		}

		public int Count {
			get { return _collection.Count; }
		}

		public bool IsEmpty() {
			return _collection.Count == 0;
		}

		public T[] ToArray() {
			var result = new T[Count];
			_collection.CopyTo(result, 0);

			return result;
		}

		public IEnumerator<T> GetEnumerator() {
			return _collection.GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator() {
			return GetEnumerator();
		}

		#region Old version

		//abstract class Source
		//{
		//    public abstract IEnumerator<T> GetEnumerator();
		//    public abstract int Count { get; }
		//    public abstract bool Contains(T item);
		//}

		//class CollectionSource : Source
		//{
		//    readonly ICollection<T> _collection;

		//    public CollectionSource(ICollection<T> collection)
		//    {
		//        _collection = collection;
		//    }

		//    public override IEnumerator<T> GetEnumerator()
		//    {
		//        return _collection.GetEnumerator();
		//    }

		//    public override int Count
		//    {
		//        get { return _collection.Count; }
		//    }

		//    public override bool Contains(T item)
		//    {
		//        return _collection.Contains(item);
		//    }
		//}

		//class EnumerableSource : Source
		//{
		//    readonly IEnumerable<T> _enumerable;
		//    int? _count;

		//    public EnumerableSource(IEnumerable<T> enumerable)
		//    {
		//        _enumerable = enumerable;
		//    }

		//    public override IEnumerator<T> GetEnumerator()
		//    {
		//        return _enumerable.GetEnumerator();
		//    }

		//    public override int Count
		//    {
		//        get
		//        {
		//            if (!_count.HasValue)
		//                _count = _enumerable.Count();

		//            return _count.Value;
		//        }
		//    }

		//    public override bool Contains(T item)
		//    {
		//        foreach (var t in _enumerable)
		//        {
		//            if (t.Equals(item))
		//                return true;
		//        }

		//        return false;
		//    }
		//}

		//readonly Source _source;

		//CollectionResult(Source source)
		//{
		//    _source = source;
		//}

		//public CollectionResult(IEnumerable<T> enumerable)
		//    : this(new EnumerableSource(enumerable))
		//{
		//}

		//public CollectionResult(ICollection<T> collection)
		//    : this(new CollectionSource(collection))
		//{
		//}

		//public int Count
		//{
		//    get { return _source.Count; }
		//}

		//public IEnumerator<T> GetEnumerator()
		//{
		//    return _source.GetEnumerator();
		//}

		//IEnumerator IEnumerable.GetEnumerator()
		//{
		//    return GetEnumerator();
		//}

		//public bool Contains(T item)
		//{
		//    return _source.Contains(item);
		//} 

		#endregion
	}
}
